#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Software: PyCharm
# @Time : 2021/05/12 10:08
# @Author : ziqi.zhang
# @Version : 1.0.0
# @Description : 封装Driver类，可供选择浏览器，默认无头模式运行，重新封装了selenium的方法

import sys
import logging
from Common.Config import ReadElement
from selenium import webdriver
from selenium.webdriver.ie.options import Options
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains


class Driver(object):
    """__init__初始化时选择浏览器驱动，重新封装selenium的方法，方便调用"""

    def __init__(self, driverName):
        """根据driverName选择浏览器驱动，以下已包含多个selenium支持的常用浏览器"""
        self.driver = driverName
        if driverName == 'chrome':
            chrome_options = webdriver.chrome.options.Options()
            # chrome_options.add_argument('--headless')  # 添加headless参数使浏览器隐藏运行，不添加则显示浏览器运行
            # chrome_options.add_argument('--disable-gpu')  # 禁用gpu渲染，与headless结合使用
            self.driver = webdriver.Chrome(options=chrome_options, service_log_path=None)
        elif driverName == 'firefox':
            firefox_options = webdriver.firefox.options.Options()
            # firefox_options.add_argument('--headless')  # 添加headless参数使浏览器隐藏运行，不添加则显示浏览器运行
            # firefox_options.add_argument('--disable-gpu')  # 禁用gpu渲染，与headless结合使用
            self.driver = webdriver.Firefox(options=firefox_options, service_log_path=None)
        elif driverName == 'ie':
            ie_options = webdriver.ie.options.Options()
            ie_options.add_argument('--headless')  # 添加headless参数使浏览器隐藏运行，不添加则显示浏览器运行
            ie_options.add_argument('--disable-gpu')  # 禁用gpu渲染，与headless结合使用
            self.driver = webdriver.Ie(options=ie_options, service_log_path=None)
        elif driverName == 'edge':
            self.driver = webdriver.Edge()
        elif driverName == 'safari':
            self.driver = webdriver.Safari()
        elif driverName == 'opera':
            self.driver = webdriver.Opera()
        else:
            logging.error("只支持chrome，firefox，ie，edge，safari，opera驱动！请查看是否输入错误的浏览器驱动！")
            sys.exit(0)  # 驱动错误则终止程序

    """以下是重新封装的selenium常用方法"""

    def get_element(self, key, section=None):
        """用来获取元素的方法"""
        read_ini = ReadElement()
        local = read_ini.get_value(key, section)
        le = local.split('^')
        try:
            if len(le) == 2:
                by = local.split('^')[0]
                local_by = local.split('^')[1]
                if by == 'id':
                    return self.by_id(local_by)
                elif by == 'name':
                    return self.by_name(local_by)
                elif by == 'class_name':
                    return self.by_class_name(local_by)
                elif by == 'css_selector':
                    return self.by_css_selector(local_by)
                elif by == 'link_text':
                    return self.by_link_text(local_by)
                elif by == 'partial_link_text':
                    return self.by_partial_link_text(local_by)
                elif by == 'xpath':
                    return self.by_xpath(local_by)
                elif by == 'tag_name':
                    return self.by_tag_name(local_by)
                elif by == 'ids':
                    return self.by_ids(local_by)
                elif by == 'names':
                    return self.by_names(local_by)
                elif by == 'class_names':
                    return self.by_class_names(local_by)
                elif by == 'css_selectors':
                    return self.by_css_selectors(local_by)
                elif by == 'link_texts':
                    return self.by_link_texts(local_by)
                elif by == 'partial_link_texts':
                    return self.by_partial_link_texts(local_by)
                elif by == 'xpaths':
                    return self.by_xpaths(local_by)
                elif by == 'tag_names':
                    return self.by_tag_names(local_by)
                else:
                    logging.error("不支持的查找元素方法，请检查key是否书写错误！")
                    sys.exit(0)  # 结束程序
            else:
                logging.error("请检查element.ini文件中的key和section是否错误！")
                sys.exit(0)  # 结束程序
        except Exception:
            raise

    def by_id(self, id):
        return WebDriverWait(self, 2, 1).until(
            lambda driver: self.driver.find_element_by_id(id),
            message=id + " not found")

    def by_name(self, name):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_element_by_name(name),
            message=name + " not found")

    def by_class_name(self, class_name):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_element_by_class_name(class_name),
            message=class_name + " not found")

    def by_css_selector(self, css_selector):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_element_by_css_selector(css_selector),
            message=css_selector + " not found")

    def by_link_text(self, link_text):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_element_by_link_text(link_text),
            message=link_text + " not found")

    def by_partial_link_text(self, partial_link_text):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_element_by_partial_link_text(partial_link_text),
            message=partial_link_text + " not found")

    def by_xpath(self, xpath):
        return WebDriverWait(self.driver, 2, 1).until(lambda driver: self.driver.find_element_by_xpath(xpath),
                                                      message=xpath + " not found")

    def by_tag_name(self, tag_name):
        return WebDriverWait(self.driver, 2, 1).until(lambda driver: self.driver.find_element_by_tag_name(tag_name),
                                                      message=tag_name + " not found")

    def by_ids(self, ids):
        return WebDriverWait(self, 2, 1).until(
            lambda driver: self.driver.find_elements_by_id(ids),
            message=ids + " not found")

    def by_names(self, names):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_elements_by_name(names),
            message=names + " not found")

    def by_class_names(self, class_names):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_elements_by_class_name(class_names),
            message=class_names + " not found")

    def by_css_selectors(self, css_selectors):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_elements_by_css_selector(css_selectors),
            message=css_selectors + " not found")

    def by_link_texts(self, link_texts):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_elements_by_link_text(link_texts),
            message=link_texts + " not found")

    def by_partial_link_texts(self, partial_link_texts):
        return WebDriverWait(self.driver, 2, 1).until(
            lambda driver: self.driver.find_elements_by_partial_link_text(partial_link_texts),
            message=partial_link_texts + " not found")

    def by_xpaths(self, xpaths):
        return WebDriverWait(self.driver, 2, 1).until(lambda driver: self.driver.find_elements_by_xpath(xpaths),
                                                      message=xpaths + " not found")

    def by_tag_names(self, tag_names):
        return WebDriverWait(self.driver, 2, 1).until(lambda driver: self.driver.find_elements_by_tag_name(tag_names),
                                                      message=tag_names + " not found")

    def execute_script(self, script, *args):
        return self.driver.execute_script(self, script, *args)

    def execute_async_script(self, script, *args):
        return self.driver.execute_async_script(self, script, *args)

    def current_url(self):
        return self.driver.current_url(self)

    def page_source(self):
        return self.driver.page_source(self)

    def current_window_handle(self):
        return self.driver.current_window_handle(self)

    def window_handles(self):
        return self.driver.window_handles(self)

    def maximize_window(self):
        return self.driver.maximize_window()

    def fullscreen_window(self):
        return self.driver.fullscreen_window()

    def minimize_window(self):
        return self.driver.minimize_window()

    def switch_to(self):
        return self.driver.switch_to(self)

    def switch_to_active_element(self):
        return self.driver.switch_to_active_element()

    def switch_to_window(self, window_name):
        return self.driver.switch_to_window(window_name)

    def switch_to_frame(self, frame_reference):
        return self.driver.switch_to_frame(frame_reference)

    def switch_to_default_content(self):
        return self.driver.switch_to_default_content()

    def switch_to_alert(self):
        return self.driver.switch_to_alert()

    def back(self):
        return self.driver.back()

    def forward(self):
        return self.driver.forward()

    def refresh(self):
        return self.driver.refresh()

    def get_cookies(self):
        return self.driver.get_cookies()

    def get_cookie(self, name):
        return self.driver.get_cookie(name)

    def delete_cookie(self, name):
        return self.driver.delete_cookie(name)

    def delete_all_cookies(self):
        return self.driver.delete_all_cookies()

    def add_cookie(self, cookie_dict):
        return self.driver.add_cookie(cookie_dict)

    def implicitly_wait(self, time_to_wait):
        return self.driver.implicitly_wait(time_to_wait)

    def set_script_timeout(self, time_to_wait):
        return self.driver.set_script_timeout(time_to_wait)

    def set_page_load_timeout(self, time_to_wait):
        return self.driver.set_page_load_timeout(time_to_wait)

    def desired_capabilities(self):
        return self.driver.desired_capabilities(self)

    def get_screenshot_as_file(self, filename):
        return self.driver.get_screenshot_as_file(filename)

    def save_screenshot(self, filename):
        return self.driver.save_screenshot(filename)

    def get_screenshot_as_png(self):
        return self.driver.get_screenshot_as_png()

    def set_window_size(self, width, height, windowHandle='current'):
        return self.driver.set_window_size(width, height, windowHandle='current')

    def get_window_size(self, windowHandle='current'):
        return self.driver.get_window_size(windowHandle='current')

    def set_window_position(self, x, y, windowHandle='current'):
        return self.driver.set_window_position(x, y, windowHandle='current')

    def get_window_position(self, windowHandle='current'):
        return self.driver.get_window_position(windowHandle='current')

    def get_window_rect(self):
        return self.driver.get_window_rect()

    def set_window_rect(self, x=None, y=None, width=None, height=None):
        return self.driver.set_window_rect(x=None, y=None, width=None, height=None)

    def file_detector(self, detector):
        return self.driver.file_detector(detector)

    def orientation(self, value):
        return self.driver.orientation(value)

    def application_cache(self):
        return self.driver.application_cache(self)

    def log_types(self):
        return self.driver.log_types(self)

    def get_log(self, log_type):
        return self.driver.get_log(log_type)

    def execute(self, driver_command):
        return self.driver.execute(self, driver_command)

    def get(self, url):
        return self.driver.get(url)

    def title(self):
        return self.driver.title(self)

    def close(self):
        return self.driver.close()

    def quit(self):
        return self.driver.quit()

    def get_screenshot_as_base64(self):
        return self.driver.get_screenshot_as_base64()

    def move_to_element(self, locator, to_element):
        if locator == 'xpath':
            element = self.by_xpath(to_element)
        elif locator == 'id':
            element = self.by_id(to_element)
        elif locator == 'name':
            element = self.by_name(to_element)
        elif locator == 'class_name':
            element = self.by_class_name(to_element)
        elif locator == 'css_selector':
            element = self.by_css_selector(to_element)
        elif locator == 'link_text':
            element = self.by_link_text(to_element)
        elif locator == 'partial_link_text':
            element = self.by_partial_link_text(to_element)
        elif locator == 'tag_name':
            element = self.by_tag_name(to_element)
        else:
            logging.error('不支持该定位方法')
            sys.exit(0)  # 结束程序
        ActionChains(self.driver).move_to_element(element).perform()
